package com.hyt.it.ogt.kq.service.gov.schedule.impl.support;

import java.util.ArrayList;
import java.util.BitSet;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import com.hyt.it.ogt.kq.service.gov.schedule.impl.ExamRoomScheduleImpl.PackageExamRoomCandidate;
import com.hyt.it.ogt.kq.service.gov.schedule.model.Candidate;
import com.hyt.it.ogt.kq.service.gov.schedule.strategy.ScheduleHelper;
import com.hyt.it.ogt.kq.service.gov.schedule.utils.GroupUtils;
import com.hyt.it.ogt.kq.service.gov.schedule.utils.SupportUtils;

/***
 * 编排方式为多科目并保持考生考场的组合考生方式
 */
public class CandidateMulAndMainten implements CandidateTogether {

    /***
     * 组合考生
     */
    @Override
    public void togetherCandidate(Map<String, Map<String, PackageExamRoomCandidate>> packageExamRoomCandidate) {
        Set<String> cacheVirCreatedIdSet = new HashSet<>();
        try {

            // 将 <批次号：<分组名：考生与考场的对应>> 转换成 <分组名：<批次号: 考生与考场的对应>>
            Map<String, Map<String, List<List<Candidate>>>> groupBatchCandidates = SupportUtils
                    .transform(packageExamRoomCandidate);
            List<String> batchNoList = new ArrayList<>(packageExamRoomCandidate.keySet());
            Collections.sort(batchNoList);

            // 按分组，将该组内多批次考生混合在一起，再进行组合虚拟考生
            for (Map.Entry<String, Map<String, List<List<Candidate>>>> entry : groupBatchCandidates.entrySet()) {
                Map<String, List<List<Candidate>>> batchCandidateMap = entry.getValue();
                Set<Candidate> candidateSet = new HashSet<>();
                batchCandidateMap.values().stream().forEach(item -> {
                    item.stream().forEach(candidateList -> {
                        candidateSet.addAll(candidateList);
                    });
                });
                this.together(candidateSet, cacheVirCreatedIdSet, batchNoList);
            }
        } finally {
            cacheVirCreatedIdSet.clear();
        }
    }

    /***
     * 组合虚拟考生
     * 
     * @param candidateSet         分组内所有批次的考生
     * @param cacheVirCreatedIdSet 已组合的考生
     * @param batchNoList          考试批次列表
     */
    private void together(Set<Candidate> candidateSet, Set<String> cacheVirCreatedIdSet, List<String> batchNoList) {
        List<Candidate> candidateList = new ArrayList<>(candidateSet);
        Map<String, BitSet> featureCodeMap = ScheduleHelper.getInstance().getCandidateBatchFeatureMap();
        // 将分组内所有批次的考生进行匹配，得到可以组合在一起的考生列表
        List<List<Candidate>> togetherCandidateList = GroupUtils.findCanTotegherCandidate(candidateList, featureCodeMap,
                batchNoList.size(), cacheVirCreatedIdSet);
        for (List<Candidate> togetherCandidate : togetherCandidateList) {
            this.createCandidateVirId(togetherCandidate, featureCodeMap, batchNoList);
        }
    }

}
